package cn.zswltech.gruul.web.api.util;

import cn.zswltech.gruul.common.constant.SystemConstant;
import cn.zswltech.gruul.domain.entity.CheckResult;
import io.jsonwebtoken.*;
import org.bouncycastle.util.encoders.Base64;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.*;


/**
 * JSON WEB TOKEN
 * Created by zhongjianwei on 2018/8/6.
 */
public class JwtUtils {
    public static String createJWT(Long userid,String id, String subject, long ttlMillis) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        SecretKey secretKey = generalKey();
        Map<String, Object> map = new HashMap<>();
        map.put("id",userid);
        JwtBuilder builder = Jwts.builder()
                .setClaims(map)
                .setId(id)
                .setSubject(subject)   // 主题
                .setIssuer("fraudmetrix")     // 签发者
                .setIssuedAt(now)      // 签发时间
                .signWith(signatureAlgorithm, secretKey); // 签名算法以及密匙
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date expDate = new Date(expMillis);
            builder.setExpiration(expDate); // 过期时间
        }
        return builder.compact();
    }

    /**
     * 验证JWT
     * @param jwtStr
     * @return
     */
    public static CheckResult validateJWT(String jwtStr) {
        CheckResult checkResult = new CheckResult();
        Claims claims;
        try {
            claims = parseJWT(jwtStr);
            checkResult.setSuccess(true);
            checkResult.setClaims(claims);
        } catch (ExpiredJwtException e) {
            checkResult.setErrCode(SystemConstant.JWT_ERRCODE_EXPIRE);
            checkResult.setSuccess(false);
        } catch (SignatureException e) {
            checkResult.setErrCode(SystemConstant.JWT_ERRCODE_FAIL);
            checkResult.setSuccess(false);
        } catch (Exception e) {
            checkResult.setErrCode(SystemConstant.JWT_ERRCODE_FAIL);
            checkResult.setSuccess(false);
        }
        return checkResult;
    }
    public static SecretKey generalKey() {
        byte[] encodedKey = Base64.decode(SystemConstant.JWT_SECERT);
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }

    /**
     *
     * 解析JWT字符串
     * @param jwt
     * @return
     * @throws Exception
     */
    public static Claims parseJWT(String jwt) throws Exception {
        SecretKey secretKey = generalKey();
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();
    }

//    public static void main(String[] args) throws Exception {
//
//        String token = JwtUtils.createJWT(Long.valueOf(1),"cb9e363e48a847b2bae601572ed5b7f7", "ApiAutoTest", 15552000000L);
//        System.out.println(token);
//        System.out.println(MD5Util.MD5(token));
//        Claims claims=parseJWT(token);
//        System.out.println(claims.getExpiration());
//        String account = (String) claims.get("sub");
//        System.out.println(account);
//
//    }
public static void main(String[] args) {
//    CheckResult checkResult1 = validateJWT("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImlzcyI6ImZyYXVkbWV0cml4IiwiaWQiOjMsImV4cCI6MTY1ODM3MDYzMCwiaWF0IjoxNjU3NzY1ODMwLCJqdGkiOiJBMTNDNDQ3QUMzMDY0NDA2RkQyOEVCMEQzQkM2MEE4MyJ9.eRzD57VNlNBuUU681z4DSVb53DKZvYuJkL8jFw-iHDk");
//    System.out.println(createJWT(3L,"asdadadadada","sss",12222222));
//    CheckResult checkResult = JwtUtils.validateJWT("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImlzcyI6ImZyYXVkbWV0cml4IiwiaWQiOjMsImV4cCI6MTY1ODIyNDczNywiaWF0IjoxNjU3NjE5OTM3LCJqdGkiOiJBMTNDNDQ3QUMzMDY0NDA2RkQyOEVCMEQzQkM2MEE4MyJ9.S5rLcm0z2UN7rFrFgezhy2DdgPzrr_6-EcHf8i_bp10");
//    if (!checkResult.isSuccess()) {
//        switch (checkResult.getErrCode()) {
//            // 签名验证不通过
//            case SystemConstant.JWT_ERRCODE_FAIL:
//                break;
//            // 签名过期，返回过期提示码
//            case SystemConstant.JWT_ERRCODE_EXPIRE:
//                break;
//            default:
//                break;
//        }
//    }
//    // 预留 判断账号是否拥有servletPath的权限
//    // 账号
//    String account = (String) checkResult.getClaims().get("sub");
//    //pwd
//    String pwd = (String) checkResult.getClaims().get("jti");
//    System.out.println(pwd);
//    System.out.println( checkResult.getClaims().keySet().toString());
//    System.out.println( checkResult.getClaims().values().toString());

}
}
